/*
在本题我们第一次DP假设第1小时于第N小时是不连续的，这样我们就可以将其当作线性DP来做，但是这样忽略的条件就是第N个小时与第1个小时连续Sleep，所以我们要在第二次DP补上，即强制第1小时Sleep，再执行一次DP。
  我们设F（i，j，0）为前 i 个小时中睡了 j 个小时，且第 j 个小时没在休息。F（i ，j，1）表示前 i 个小时中睡了 j 个小时，且第 j 个小时在休息。那么显而易见
  F（i，j，0）= max{F（i-1，j，0）F（i-1，j，1）}。
  F（i，j，1）= max{F（i-1，j-1，1）+ val（i），F（i-1，j-1，0）}
  至于第二次DP，我们只需将初始值令F（1，1，1） = val（1）即可。
*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,b;
const int maxn = 4000;
int val[maxn];
int f[2][maxn][2];
void solve(){
	memset (f, 0x80, sizeof f);
	f[1][0][0] = 0;
	f[1][1][1] = 0;
	for(int i = 2;i <= n;i++){
		for(int j = 0;j <= b;j++){
			f[i&1][j][0] = max(f[(i-1)&1][j][1],f[(i-1)&1][j][0]);
			if(j-1 >= 0) f[i&1][j][1] = max(f[(i-1)&1][j-1][1]+val[i],f[(i-1)&1][j-1][0]);
		}
	}
	int ans = max(f[n&1][b][0],f[n&1][b][1]);
	memset (f, 0x80, sizeof f);
	f[1][1][1] = val[1];
	for(int i = 2;i <= n;i++){
		for(int j = 0;j <= b;j++){
			f[i&1][j][0] = max(f[(i-1)&1][j][1],f[(i-1)&1][j][0]);
			if(j-1 >= 0)f[i&1][j][1] = max(f[(i-1)&1][j-1][1]+val[i],f[(i-1)&1][j-1][0]);
		}
	}
	printf("%d\n",max(f[n&1][b][1],ans));
}
int main(){
	//ios::sync_with_stdio(false);
	scanf("%d%d",&n,&b);
	for(int i = 1;i <= n;i++){
		scanf("%d",val+i);
	}
	solve();
	return 0;
}
